import { _decorator, CCFloat, Component, log, Node, tween, Tween, Widget } from 'cc';
import ViewAnimBase from './ViewAnimBase';
import _ from 'lodash';
const { ccclass, property, menu } = _decorator;



export const VIEW_ANIM_EVENT = {
    Show: "Show",
    Close: "Close",
    Remove: 'Remove',
    Removed: 'Removed',

    InStart:"anim-in-start",
    InDone:"anim-in-done",
    
    OutStart: "anim-out-start",
    OutDone: "anim-out-done",
    
}




const enum VIEW_STATE {
    None = 0,
    AnimIn,
    Idle,
    AnimOut
}



@ccclass('ViewAnimCtrl')
@menu('ViewAnim/ViewAnimCtrl')
export class ViewAnimCtrl extends Component {
    @property({
        displayName: "启动播放"
    })
    playOnLoad: boolean = true;

    @property({
        displayName: '延迟时间',
        visible(){return this.playOnLoad == true;}
    })
    playOnLoadDelay: number = 0;

    @property(CCFloat )
    logicInDuration:number = 0.12;

    @property(CCFloat)
    logicOutDuration:number = 0.1;

    private animComponents: ViewAnimBase[] = [];
    
    private state:VIEW_STATE = VIEW_STATE.None;

    protected __preload(): void {
        let widget = this.getComponent( Widget )
        if( widget ) {
            widget.updateAlignment();
            widget.enabled = widget.alignMode == Widget.AlignMode.ALWAYS;
        }
    }

    protected onLoad(): void {
        // @ts-ignore
        this.animComponents = this.node.getComponentsInChildren(ViewAnimBase);

        this.node.on( VIEW_ANIM_EVENT.Show,     this.onShowEvent,    this);
        this.node.on( VIEW_ANIM_EVENT.Close,    this.onCloseEvent,   this);
    }   


    private onShowEvent(){
        this.state = VIEW_STATE.Idle;
        this.onShow();
    }

    private onCloseEvent() {
        this.onClose();
    }


    protected onEnable(): void {

        this.state = VIEW_STATE.Idle;
        if( this.playOnLoad ) {
            this.playOnLoadDelay = this.playOnLoadDelay ?? 0;
            if( this.playOnLoadDelay > 0 ) {
                this.scheduleOnce( () => {
                    this.onShow();
                },  this.playOnLoadDelay);
            }else{
                this.onShow();
            }
        }   
    }


    
    private _runInAction( callback ) {
        for (let index = 0; index < this.animComponents.length; index++) {
            let component = this.animComponents[index];
            component.runInAction( this.logicInDuration );
        }
        tween( this.node )
            .delay( this.logicInDuration )
            .call( callback )
            .start()
    }


    private _runOutAction( callback ){
        for (let index = 0; index < this.animComponents.length; index++) {
            let component = this.animComponents[index];
            component.runOutAction( this.logicOutDuration );
        };

        tween( this.node )
            .delay( this.logicOutDuration )
            .call( callback )
            .start()
    }

    onShow() {
        this.state = VIEW_STATE.AnimIn;
        this._runInAction( () => {
            this.state = VIEW_STATE.Idle;
            this.node.emit( VIEW_ANIM_EVENT.InDone );
        });
        this.node.emit(  VIEW_ANIM_EVENT.InStart );
    }


    onClose() {
        
        if( this.state >= VIEW_STATE.AnimOut ) return;
        this.state = VIEW_STATE.AnimOut;

        this._runOutAction( () => {
            this.node.emit( VIEW_ANIM_EVENT.OutDone );
            this.node.emit( VIEW_ANIM_EVENT.Remove, this);
        });       
        this.node.emit( VIEW_ANIM_EVENT.OutStart );  
    }


}


